/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


import { ts, ClassSignature, MethodSignature, ArkMethod, ArkAssignStmt, AbstractBinopExpr, ArkFile, Stmt } from "arkanalyzer/lib";
import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger';
import { BaseChecker, BaseMetaData } from "../BaseChecker";
import { Defects } from "../../model/Defects";
import { ClassMatcher, FileMatcher, MatcherCallback, MatcherTypes, MethodMatcher } from "../../matcher/Matchers";
import { Rule } from "../../model/Rule";
import { RuleListUtil } from "../../utils/common/DefectsList";
import { IssueReport } from '../../model/Defects';
const defaultOptions: Options = {
    allowAny: true,
    allowBoolean: true,
    allowNullish: true,
    allowNumberAndString: true,
    allowRegExp: true,
    skipCompoundAssignments: false
}
interface Options {
    allowAny: boolean,
    allowBoolean: boolean,
    allowNullish: boolean,
    allowNumberAndString: boolean,
    allowRegExp: boolean,
    skipCompoundAssignments: boolean
}
type stmtType = {
    classSignature?: ClassSignature,
    methodSignature?: MethodSignature,
    realGenericTypes: string[]
}
type LeftOp = {
    constFlag: boolean,
    declaringStmt: Stmt,
    name: string,
    originalValue: string,
    type: stmtType,
    usedStmts: ArkAssignStmt[]
}
const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'RestrictPlusOperandsCheck');
const gmetaData: BaseMetaData = {
    severity: 2,
    ruleDocPath: "docs/restrict-plus-operands-check.md", // TODO: support url
    description: "Require both operands of addition to be the same type and be bigint, number, or string."
};
export class RestrictPlusOperandsCheck implements BaseChecker {
    readonly metaData: BaseMetaData = gmetaData;
    public rule: Rule;
    public defects: Defects[] = [];
    public issues: IssueReport[] = [];
    private fileMatcher: FileMatcher = {
        matcherType: MatcherTypes.FILE,
    };
    private classMatcher: ClassMatcher = {
        file: [this.fileMatcher],
        matcherType: MatcherTypes.CLASS
    };
    private methodMatcher: MethodMatcher = {
        matcherType: MatcherTypes.METHOD,
        class: [this.classMatcher]
    };
    public registerMatchers(): MatcherCallback[] {
        const matchBuildCb: MatcherCallback = {
            matcher: this.methodMatcher,
            callback: this.check
        }
        return [matchBuildCb];
    }
    public check = (method: ArkMethod) => {
        let declareClass = method.getDeclaringArkClass();
        const arkFile = declareClass.getDeclaringArkFile();
        // 将规则选项转换为Options类型
        let options: Options;
        if (this.rule && this.rule.option.length > 0) {
            options = this.rule.option[0] as Options;
        } else {
            options = defaultOptions;
        }
        // 初始化匹配名称数组和所有文本数组
        let matchNames: string[] = [];
        // 遍历方法体中的所有语句
        for (let stmt of method.getBody()?.getCfg().getStmts() ?? []) {
            // 获取语句的原始文本
            let text = stmt.getOriginalText() ?? '';
            if (!text) {
                continue;
            }
            // 如果语句不是ArkAssignStmt类型的，则跳过
            if (!(stmt instanceof ArkAssignStmt)) {
                continue;
            }

            // 获取赋值语句的右侧操作数
            let rightOp = stmt.getRightOp();
            if (!rightOp) {
                continue;
            }
            // 如果文本匹配parseInt函数，并且右侧操作数不是二元操作符表达式或者操作符不是加号，则跳过
            if (this.matchParseInt(text)) {
                if (!(rightOp instanceof AbstractBinopExpr) || rightOp.getOperator() !== '+') {
                    continue;
                }
                let op1 = rightOp.getOp1();
                let op2 = rightOp.getOp2();
                if (op1 !== op2) {
                    continue;
                }
                this.addIssueReport(stmt, arkFile, text);
            }
            // 获取右侧操作数的类型
            let rightOpType = rightOp.getType();
            let rightOpTypeString = rightOpType.toString();
            // 如果右侧操作数类型为number，并且可以从文本中提取BigInt变量名
            if (rightOpTypeString == 'number' && this.extractBigIntVariableName(text)) {
                let matchName = this.extractBigIntVariableName(text);
                if (matchName) {
                    matchNames.push(matchName);
                }
            }
            // 如果右侧操作数不是二元操作符表达式或者操作符不是加号，则跳过
            if (!(rightOp instanceof AbstractBinopExpr) || rightOp.getOperator() !== '+') {
                continue;
            }
            // 获取赋值语句的原始文本
            let textPlus = stmt.getOriginalText() ?? '';
            if (this.variablePlus(textPlus)) {
                // 获取二元操作符表达式的两个操作数
                let op1 = rightOp.getOp1();
                let op1String = op1.toString();
                let op2 = rightOp.getOp2();
                let op2String = op2.toString();
                let op1TypeString = op1.getType().toString();
                let op2TypeString = op2.getType().toString();
                if (this.typeDifferent(op1TypeString, op2TypeString)) {
                    this.addIssueReport(stmt, arkFile, text, options, op1TypeString, op2TypeString, op1String, op2String)
                }
            }
            // 获取二元操作符表达式的两个操作数
            let op1 = rightOp.getOp1();
            let op2 = rightOp.getOp2();
            let op1TypeString = op1.getType().getTypeString();
            let op2TypeString = op2.getType().getTypeString();
            let op1Name = op1.toString();
            let op2Name = op2.toString();
            // 执行通用检查，如果检查结果为true，则添加问题报告
            if (this.generalInspection(op1Name, op2Name, op1TypeString, op2TypeString, matchNames, textPlus)) {
                if (this.bigIntPlusNumber(textPlus)) {
                    op1TypeString == 'bigint';
                }
                const regex = /\s*([^=,\s]+(?:\s+[^=,\s]+)*)/g;
                const match = text.match(regex);
                if (match) {
                    const afterEqual = match[1]?.trim();
                    if (this.templateExpression(text)) {
                        continue;
                    }
                    if (afterEqual) {
                        this.addIssueReport(stmt, arkFile, afterEqual, options, op1TypeString, op2TypeString, op1Name, op2Name);
                    }
                }
            }
        }
    }
    /**
     * 判断给定的文本字符串中是否包含方括号 []
     *
     * @param text 要检查的文本字符串
     * @returns 如果文本中包含方括号，则返回 true；否则返回 false
     */
    private SquareBrackets(text: string) {
        return /\[\]/g.test(text);
    }
    /**
     * 判断传入的字符串是否符合变量加法的正则表达式规则
     *
     * @param text 待判断的字符串
     * @returns 如果字符串符合变量加法的正则表达式规则，则返回 true，否则返回 false
     */
    private variablePlus(text: string) {
        return /^[a-zA-Z_]\w*\s\+\s[a-zA-Z_]\w*$/.test(text);
    }
    /**
     * 检查文本中是否包含模板表达式
     *
     * @param text 要检查的文本
     * @returns 如果文本中包含模板表达式，则返回true，否则返回false
     */
    private templateExpression(text: string) {
        return /\$\{.*?\}/.test(text);
    }

    private generalInspection(op1Name?: string, op2Name?: string, op1TypeString?: string, op2TypeString?: string, matchNames?: string[], textPlus?: string): boolean {
        const textPlusCheck = textPlus ?? ''
        const op1NameCheck = op1Name ?? ''
        const op2NameCheck = op2Name ?? ''
        const op1TypeStringCheck = op1TypeString ?? ''
        const op2TypeStringCheck = op2TypeString ?? ''
        const matchNamesCheck = matchNames ?? []
        return this.bigIntPlusNumber(textPlusCheck) || this.typeDifferent(op1TypeStringCheck, op2TypeStringCheck) || this.variableBigintPlusNumber(op1NameCheck, op2NameCheck, matchNamesCheck)
    }
    //检查两个操作数名称中是否有一个与给定的匹配名称数组中的某个名称相同，且另一个操作数名称与这个匹配名称不同。
    private variableBigintPlusNumber(op1Name: string, op2Name: string, matchNames: string[]): boolean {
        for (let matchName of matchNames) {
            if (op1Name === matchName) {
                if (op2Name !== matchName) {
                    return true;
                }
            } else if (op2Name === matchName) {
                if (op1Name !== matchName) {
                    return true;
                }
            }
        }
        return false;
    }
    //判断字符串是否表示一个有效的 bigInt 与数字的加法运算表达式
    private bigIntPlusNumber(textPlus: string,): boolean {
        if (this.bigintPlusNumberMatch(textPlus)) {
            return true;
        }
        return false;
    }
    //判断两个操作数类型字符串是否不同
    private typeDifferent(op1TypeString: string, op2TypeString: string): boolean {
        if (op1TypeString !== op2TypeString) {
            return true;
        }
        return false;
    }
    // 提取变量名，例如：const a = 1n; 或 let b = 2n; 等语句中的 'a' 和 'b'
    private extractBigIntVariableName(text: string): string | null {
        const regex = /\b(const|let|var)\s+(\w+)\s*=\s*\d+n\s*;\s*/;
        const match = text.match(regex);
        if (match) {
            // match[0] 是整个匹配的字符串
            // match[1] 是 const、let 或 var
            // match[2] 是变量名
            return match[2];
        } else {
            return null; // 没有找到匹配项
        }
    }
    // 检测是否存在 bigint + number 的情况，例如：a = 1n + 1; 或 a = 1 + 1n;
    private bigintPlusNumberMatch(text: string) {
        return /=\s*\b(\d+n)\s*\+\s*(\d+)\b/.test(text);
    }
    //判断给定的文本中是否包含 parseInt 函数调用
    private matchParseInt(text: string) {
        return /=\s*parseInt\s*\([^)]*\)/.test(text);
    }
    public checkCompoundAssignment(code: string): boolean {
        // 创建一个源代码文件对象
        const sourceFile = ts.createSourceFile('temp.ts', code, ts.ScriptTarget.Latest, true);
        let found: boolean = false;

        // 定义一个函数来检查节点
        function checkNode(node: ts.Node) {
            // 检查节点是否是二元表达式
            if (ts.isBinaryExpression(node)) {
                // 然后检查操作符是否为复合赋值符
                const operator = node.operatorToken.getText();
                if (['+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=', '&=', '^=', '|='].includes(operator)) {
                    found = true;
                }
            }
            // 递归检查节点的所有子节点
            ts.forEachChild(node, checkNode);
        }

        // 从源代码文件的根节点开始检查
        checkNode(sourceFile);

        // 返回是否找到了复合赋值符
        return found;
    }
    private addIssueReport(stmt: Stmt, arkFile: ArkFile, name: string, options?: Options, op1TypeString?: string, op2TypeString?: string, op1String?: string, op2String?: string) {
        const op1TypeStringCheck = op1TypeString ?? ''
        const op2TypeStringCheck = op2TypeString ?? ''
        const op1StringCheck = op1String ?? '';
        const op2StringCheck = op2String ?? '';
        const optionsCheck = options ?? defaultOptions
        const severity = this.rule.alert ?? this.metaData.severity;
        const warnInfo = this.getLineAndColumn(stmt, arkFile, name, optionsCheck, op1TypeStringCheck, op2TypeStringCheck, op1StringCheck, op2StringCheck);
        if (warnInfo) {
            this.metaData.description = this.metaData.description.padEnd(130);
            const filePath = arkFile.getFilePath();
            let defects = new Defects(warnInfo.line, warnInfo.startCol, warnInfo.endCol, this.metaData.description, severity, this.rule.ruleId, filePath,
                this.metaData.ruleDocPath, true, false, false);
            RuleListUtil.push(defects);
        }
    }
    private getLineAndColumn(stmt: Stmt, arkFile: ArkFile, name: string, options: Options, op1TypeString: string, op2TypeString: string, op1String: string, op2String: string) {
        if (arkFile) {
            const code = arkFile.getCode() ?? '';
            const lines = code.split('\r\n');
            for (let i = 0; i < lines.length; i++) {
                const line = lines[i];
                const nextLine = lines[i + 1];
                let nameIndex = line.indexOf(name);
                if (nameIndex !== -1) {
                    const originPosition = stmt.getOriginPositionInfo();
                    const targetLine = originPosition.getLineNo();
                    //精准找到错误的变量名所在的行列号
                    // 选项都不是默认配置时
                    if (options.allowAny == false && options.allowBoolean == false && options.allowNullish == false && options.allowNumberAndString == false && options.allowRegExp == false && options.skipCompoundAssignments == true) {
                        if (this.SquareBrackets(op1TypeString) || op1TypeString == 'never' || op1TypeString == 'UnknownKeyword' || op1TypeString == 'any' || op1TypeString == 'boolean' || op1TypeString == 'null' || op1TypeString == 'undefined' || op1TypeString == 'RegExp') {
                            const op1Index = line.lastIndexOf(op1String);
                            if (op1Index !== -1) {
                                const startCol = op1Index + 1; // 列号从1开始
                                const endCol = op1Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (this.SquareBrackets(op2TypeString) || op2TypeString == 'never' || op2TypeString == 'UnknownKeyword' || op2TypeString == 'any' || op2TypeString == 'boolean' || op2TypeString == 'null' || op2TypeString == 'undefined' || op2TypeString == 'RegExp') {
                            const op2Index = line.lastIndexOf(op2String);
                            if (op2Index !== -1) {
                                const startCol = op2Index + 1; // 列号从1开始
                                const endCol = op2Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else {
                            const text = stmt.getOriginalText() ?? '';
                            if (!text) {
                                continue;
                            }
                            if (!(stmt instanceof ArkAssignStmt)) {
                                continue;
                            }
                            if (this.checkCompoundAssignment(text)) {
                                continue;
                            }
                            const startCol = nameIndex + 1; // 列号从1开始
                            const endCol = nameIndex + 1;
                            const originPath = arkFile.getFilePath();
                            return { line: targetLine, startCol, endCol, filePath: originPath };
                        }
                    }
                    //allowAny为true时，允许any类型
                    if (options.allowAny == true && options.allowBoolean == false && options.allowNullish == false && options.allowNumberAndString == false && options.allowRegExp == false && options.skipCompoundAssignments == true) {
                        if (this.SquareBrackets(op1TypeString) || op1TypeString == 'never' || op1TypeString == 'UnknownKeyword' || op1TypeString == 'boolean' || op1TypeString == 'null' || op1TypeString == 'undefined' || op1TypeString == 'RegExp') {
                            const op1Index = line.lastIndexOf(op1String);
                            if (op1Index !== -1) {
                                const startCol = op1Index + 1; // 列号从1开始
                                const endCol = op1Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (this.SquareBrackets(op2TypeString) || op2TypeString == 'never' || op2TypeString == 'UnknownKeyword' || op2TypeString == 'boolean' || op2TypeString == 'null' || op2TypeString == 'undefined' || op2TypeString == 'RegExp') {
                            const op2Index = line.lastIndexOf(op2String);
                            if (op2Index !== -1) {
                                const startCol = op2Index + 1; // 列号从1开始
                                const endCol = op2Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (op1TypeString == 'any' || op2TypeString == 'any') {
                            continue;
                        }
                        else {
                            const text = stmt.getOriginalText() ?? '';
                            if (!text) {
                                continue;
                            }
                            if (!(stmt instanceof ArkAssignStmt)) {
                                continue;
                            }
                            if (this.checkCompoundAssignment(text)) {
                                continue;
                            }
                            const startCol = nameIndex + 1; // 列号从1开始
                            const endCol = nameIndex + 1;
                            const originPath = arkFile.getFilePath();
                            return { line: targetLine, startCol, endCol, filePath: originPath };
                        }
                    }
                    //allowBoolean为true时，允许boolean类型
                    if (options.allowBoolean == true && options.allowAny == false && options.allowNullish == false && options.allowNumberAndString == false && options.allowRegExp == false && options.skipCompoundAssignments == true) {
                        if (this.SquareBrackets(op1TypeString) || op1TypeString == 'never' || op1TypeString == 'UnknownKeyword' || op1TypeString == 'any' || op1TypeString == 'null' || op1TypeString == 'undefined' || op1TypeString == 'RegExp') {
                            const op1Index = line.lastIndexOf(op1String);
                            if (op1Index !== -1) {
                                const startCol = op1Index + 1; // 列号从1开始
                                const originPath = arkFile.getFilePath();
                                const endCol = op1Index + 1;

                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (this.SquareBrackets(op2TypeString) || op2TypeString == 'never' || op2TypeString == 'UnknownKeyword' || op2TypeString == 'any' || op2TypeString == 'null' || op2TypeString == 'undefined' || op2TypeString == 'RegExp') {
                            const op2Index = line.lastIndexOf(op2String);
                            if (op2Index !== -1) {
                                const startCol = op2Index + 1; // 列号从1开始
                                const endCol = op2Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (op1TypeString == 'boolean' || op2TypeString == 'boolean') {
                            continue;
                        }
                        else {
                            const text = stmt.getOriginalText() ?? '';
                            if (!text) {
                                continue;
                            }
                            if (!(stmt instanceof ArkAssignStmt)) {
                                continue;
                            }
                            if (this.checkCompoundAssignment(text)) {
                                continue;
                            }
                            const startCol = nameIndex + 1; // 列号从1开始
                            const endCol = nameIndex + 1;
                            const originPath = arkFile.getFilePath();
                            return { line: targetLine, startCol, endCol, filePath: originPath };
                        }
                    }
                    //allowNullish为true时，允许null和undefined类型
                    if (options.allowNullish == true && options.allowAny == false && options.allowBoolean == false && options.allowNumberAndString == false && options.allowRegExp == false && options.skipCompoundAssignments == true) {
                        if (this.SquareBrackets(op1TypeString) || op1TypeString == 'never' || op1TypeString == 'UnknownKeyword' || op1TypeString == 'any' || op1TypeString == 'boolean') {
                            const op1Index = line.lastIndexOf(op1String);
                            if (op1Index !== -1) {
                                const startCol = op1Index + 1; // 列号从1开始
                                const endCol = op1Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (this.SquareBrackets(op2TypeString) || op2TypeString == 'never' || op2TypeString == 'UnknownKeyword' || op2TypeString == 'any' || op2TypeString == 'boolean' || op2TypeString == 'RegExp') {
                            const op2Index = line.lastIndexOf(op2String);
                            if (op2Index !== -1) {
                                const startCol = op2Index + 1; // 列号从1开始
                                const endCol = op2Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (op1TypeString == 'null' || op2TypeString == 'null' || op1TypeString == 'undefined' || op2TypeString == 'undefined') {
                            continue;
                        }
                        else {
                            const text = stmt.getOriginalText() ?? '';
                            if (!text) {
                                continue;
                            }
                            if (!(stmt instanceof ArkAssignStmt)) {
                                continue;
                            }
                            if (this.checkCompoundAssignment(text)) {
                                continue;
                            }
                            const startCol = nameIndex + 1; // 列号从1开始
                            const endCol = nameIndex + 1;
                            const originPath = arkFile.getFilePath();
                            return { line: targetLine, startCol, endCol, filePath: originPath };
                        }
                    }
                    //allowNumberAndString为true时,允许变量a为string类型,变量b为number类型,相反同理
                    if (options.allowNumberAndString == true && options.allowAny == false && options.allowBoolean == false && options.allowNullish == false && options.allowRegExp == false && options.skipCompoundAssignments == true) {
                        if (this.SquareBrackets(op1TypeString) || op1TypeString == 'never' || op1TypeString == 'UnknownKeyword' || op1TypeString == 'any' || op1TypeString == 'boolean' || op1TypeString == 'null' || op1TypeString == 'undefined' || op1TypeString == 'RegExp') {
                            const op1Index = line.lastIndexOf(op1String);
                            if (op1Index !== -1) {
                                const startCol = op1Index + 1; // 列号从1开始
                                const endCol = op1Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (this.SquareBrackets(op2TypeString) || op2TypeString == 'never' || op2TypeString == 'UnknownKeyword' || op2TypeString == 'any' || op2TypeString == 'boolean' || op2TypeString == 'null' || op2TypeString == 'undefined' || op2TypeString == 'RegExp') {
                            const op2Index = line.lastIndexOf(op2String);
                            if (op2Index !== -1) {
                                const startCol = op2Index + 1; // 列号从1开始
                                const endCol = op2Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (op1TypeString == 'number|string' || op1TypeString == 'string|number') {
                            if (op2TypeString == 'string' || op2TypeString == 'number') {
                                continue;
                            }
                        }
                        else if (op2TypeString == 'number|string' || op2TypeString == 'string|number') {
                            if (op1TypeString == 'string' || op1TypeString == 'number') {
                                continue;
                            }
                        }
                        else if (op1TypeString == 'string' && op2TypeString == 'number') {
                            continue;
                        }
                        else if (op1TypeString == 'number' && op2TypeString == 'string') {
                            continue;
                        }
                        else {
                            const text = stmt.getOriginalText() ?? '';
                            if (!text) {
                                continue;
                            }
                            if (!(stmt instanceof ArkAssignStmt)) {
                                continue;
                            }
                            if (this.checkCompoundAssignment(text)) {
                                continue;
                            }
                            const startCol = nameIndex + 1; // 列号从1开始
                            const endCol = nameIndex + 1;
                            const originPath = arkFile.getFilePath();
                            return { line: targetLine, startCol, endCol, filePath: originPath };
                        }
                    }
                    //allowRegExp为true时,允许变量a为string类型,变量b为RegExp类型,相反同理
                    if (options.allowRegExp == true && options.allowAny == false && options.allowBoolean == false && options.allowNullish == false && options.allowNumberAndString == false && options.skipCompoundAssignments == true) {
                        if (this.SquareBrackets(op1TypeString) || op1TypeString == 'never' || op1TypeString == 'UnknownKeyword' || op1TypeString == 'any' || op1TypeString == 'boolean' || op1TypeString == 'null' || op1TypeString == 'undefined') {
                            const op1Index = line.lastIndexOf(op1String);
                            if (op1Index !== -1) {
                                const startCol = op1Index + 1; // 列号从1开始
                                const endCol = op1Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (this.SquareBrackets(op2TypeString) || op2TypeString == 'never' || op2TypeString == 'UnknownKeyword' || op2TypeString == 'any' || op2TypeString == 'boolean' || op2TypeString == 'null' || op2TypeString == 'undefined') {
                            const op2Index = line.lastIndexOf(op2String);
                            if (op2Index !== -1) {
                                const startCol = op2Index + 1; // 列号从1开始
                                const endCol = op2Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (op1TypeString == 'string' && op2TypeString == 'RegExp') {
                            continue;
                        }
                        else if (op2TypeString == 'string' && op1TypeString == 'RegExp') {
                            continue;
                        }
                        else {
                            const text = stmt.getOriginalText() ?? '';
                            if (!text) {
                                continue;
                            }
                            if (!(stmt instanceof ArkAssignStmt)) {
                                continue;
                            }
                            if (this.checkCompoundAssignment(text)) {
                                continue;
                            }
                            const startCol = nameIndex + 1; // 列号从1开始
                            const endCol = nameIndex + 1;
                            const originPath = arkFile.getFilePath();
                            return { line: targetLine, startCol, endCol, filePath: originPath };
                        }
                    }
                    //skipCompoundAssignments为false时检查组合赋值符,例如+=,-=,*=等
                    if (options.skipCompoundAssignments == false && options.allowRegExp == false && options.allowAny == false && options.allowBoolean == false && options.allowNullish == false && options.allowNumberAndString == false) {
                        const text = stmt.getOriginalText() ?? '';
                        if (!text) {
                            continue;
                        }
                        if (!(stmt instanceof ArkAssignStmt)) {
                            continue;
                        }
                        if (this.checkCompoundAssignment(text)) {
                            if (!(stmt instanceof ArkAssignStmt)) {
                                continue;
                            }
                            const leftOp = stmt.getLeftOp();
                            const leftOpName = leftOp.toString();
                            const rightOp = stmt.getRightOp();
                            if (leftOpName == op1String) {
                                if (!(rightOp instanceof AbstractBinopExpr)) {
                                    continue;
                                }
                                const op2 = rightOp.getOp2();
                                const op2Type = op2.getType().toString();
                                if (op1TypeString != op2Type) {
                                    const op1Index = line.lastIndexOf(op2String);
                                    if (op1Index !== -1) {
                                        const startCol = op1Index + 1; // 列号从1开始
                                        const endCol = op1Index + 1;
                                        const originPath = arkFile.getFilePath();
                                        return { line: targetLine, startCol, endCol, filePath: originPath }
                                    }
                                }
                            }
                        }
                        if (this.SquareBrackets(op1TypeString) || op1TypeString == 'never' || op1TypeString == 'UnknownKeyword' || op1TypeString == 'any' || op1TypeString == 'boolean' || op1TypeString == 'null' || op1TypeString == 'undefined' || op1TypeString == 'RegExp') {
                            const op1Index = line.lastIndexOf(op1String);
                            if (op1Index !== -1) {
                                const startCol = op1Index + 1; // 列号从1开始
                                const endCol = op1Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (this.SquareBrackets(op2TypeString) || op2TypeString == 'never' || op2TypeString == 'UnknownKeyword' || op2TypeString == 'any' || op2TypeString == 'boolean' || op2TypeString == 'null' || op2TypeString == 'undefined' || op2TypeString == 'RegExp') {
                            const op2Index = line.lastIndexOf(op2String);
                            if (op2Index !== -1) {
                                const startCol = op2Index + 1; // 列号从1开始
                                const endCol = op2Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else {
                            const startCol = nameIndex + 1; // 列号从1开始
                            const endCol = nameIndex + 1;
                            const originPath = arkFile.getFilePath();
                            return { line: targetLine, startCol, endCol, filePath: originPath }
                        }
                    }
                    //选项都是默认配置时
                    if (options.allowAny == true && options.allowBoolean == true && options.allowNullish == true && options.allowNumberAndString == true && options.allowRegExp == true && options.skipCompoundAssignments == false) {
                        const text = stmt.getOriginalText() ?? '';
                        if (!text) {
                            continue;
                        }
                        if (!(stmt instanceof ArkAssignStmt)) {
                            continue;
                        }
                        if (this.checkCompoundAssignment(text)) {
                            if (!(stmt instanceof ArkAssignStmt)) {
                                continue;
                            }
                            const leftOp = stmt.getLeftOp();
                            const leftOpName = leftOp.toString();
                            const rightOp = stmt.getRightOp();
                            if (leftOpName == op1String) {
                                if (!(rightOp instanceof AbstractBinopExpr)) {
                                    continue;
                                }
                                const op2 = rightOp.getOp2();
                                const op2Type = op2.getType().toString();
                                if (op1TypeString != op2Type) {
                                    const op1Index = line.lastIndexOf(op2String);
                                    if (op1Index !== -1) {
                                        const startCol = op1Index + 1; // 列号从1开始
                                        const endCol = op1Index + 1;
                                        const originPath = arkFile.getFilePath();
                                        return { line: targetLine, startCol, endCol, filePath: originPath }
                                    }
                                }
                            }
                        }
                        if (this.SquareBrackets(op1TypeString) || op1TypeString == 'never' || op1TypeString == 'UnknownKeyword') {
                            const op1Index = line.lastIndexOf(op1String);
                            if (op1Index !== -1) {
                                const startCol = op1Index + 1; // 列号从1开始
                                const endCol = op1Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (this.SquareBrackets(op2TypeString) || op2TypeString == 'never' || op2TypeString == 'UnknownKeyword') {
                            const op2Index = line.lastIndexOf(op2String);
                            if (op2Index !== -1) {
                                const startCol = op2Index + 1; // 列号从1开始
                                const endCol = op2Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (op1TypeString == 'number' && op2TypeString == 'RegExp') {
                            const op2Index = line.lastIndexOf(op2String);
                            if (op2Index !== -1) {
                                const startCol = op2Index + 1; // 列号从1开始
                                const endCol = op2Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (op1TypeString == 'RegExp' && op2TypeString == 'number') {
                            const op2Index = line.lastIndexOf(op2String);
                            if (op2Index !== -1) {
                                const startCol = op2Index + 1; // 列号从1开始
                                const endCol = op2Index + 1;
                                const originPath = arkFile.getFilePath();
                                return { line: targetLine, startCol, endCol, filePath: originPath }
                            }
                        }
                        else if (op1TypeString == 'any' || op2TypeString == 'any') {
                            continue;
                        }
                        else if (op1TypeString == 'boolean' || op2TypeString == 'boolean') {
                            continue;
                        }
                        else if (op1TypeString == 'null' || op2TypeString == 'null' || op1TypeString == 'undefined' || op2TypeString == 'undefined') {
                            continue;
                        }
                        else if (op1TypeString == 'number|string' || op1TypeString == 'string|number') {
                            if (op2TypeString == 'string' || op2TypeString == 'number') {
                                continue;
                            }
                        }
                        else if (op2TypeString == 'number|string' || op2TypeString == 'string|number') {
                            if (op1TypeString == 'string' || op1TypeString == 'number') {
                                continue;
                            }
                        }
                        else if (op1TypeString == 'string' && op2TypeString == 'number') {
                            continue;
                        }
                        else if (op1TypeString == 'number' && op2TypeString == 'string') {
                            continue;
                        }
                        else if (op1TypeString == 'string' && op2TypeString == 'RegExp') {
                            continue;
                        }
                        else if (op2TypeString == 'string' && op1TypeString == 'RegExp') {
                            continue;
                        }
                        else {
                            const startCol = nameIndex + 1; // 列号从1开始
                            const endCol = nameIndex + 1;
                            const originPath = arkFile.getFilePath();
                            return { line: targetLine, startCol, endCol, filePath: originPath }
                        }
                    }
                }
            }
        } else {
            logger.debug('arkFile is null');
        }
        return null;
    }
}